/*
 * Copyright  2018 Linkel Technology Co., Ltd, Beijing
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BA SIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
import React from "react";

import {
    ShowController,
    ShowView,
    SelectInput,
    TabbedShowLayout,
    Tab, RadioButtonGroupInput,
    FormTab, ReferenceInput,
    TabbedForm, FormDataConsumer,
    Filter,
    DateField,
    Responsive,
    SimpleList,
    List,
    Create,
    Datagrid,
    TextField,
    RichTextField,
    BooleanField,
    NumberField,
    ChipField,
    ReferenceField,
    ShowButton,
    LongTextInput,
    TextInput,
    NumberInput,
    ArrayInput,
    SimpleFormIterator,
    required,
} from "react-admin/lib";

import CreateToolbar from "./CreateToolbar";
import CodeField from "./CodeField";
import ArgField from "./ArgField";

const TransFilter = (props) => (
    <Filter {...props}>
        <TextInput label="交易标识" source="txid_contains" alwaysOn />
    </Filter>
);

export const TransList = (props) => (
    <List
        {...props}
        filters={<TransFilter />}
        sort={{ field: "timestamp", order: "DESC" }}
        bulkActions={false}
    >
        <Responsive
            small={
                <SimpleList
                    primaryText={(record) => {
                        if (record.txid.length > 35) {
                            return `${record.txid.slice(0, 35)}...`;
                        }
                        return record.txid;
                    }}
                    secondaryText={(record) => record.block.id}
                    tertiaryText={(record) => new Date(record.timestamp).toLocaleDateString()}
                    linkType="show"
                />
            }
            medium={
                <Datagrid>
                    <TextField source="txid" />
                    <DateField source="timestamp" showTime options={{ hour12: false }} />
                    <ChipField source="type" />
                    <TextField source="chaincodeID.chaincodeName" sortable={false} />
                    <ShowButton />
                </Datagrid>
            }
        />
    </List>
);

const TransTitle = ({ record }) => <span> {record ? `${record.txid}` : ""}</span>;

export const TransShow = (props) => (
    <ShowController title={<TransTitle />} {...props}>
        {
            (controllerProps) => <ShowView {...props} {...controllerProps}>
                <TabbedShowLayout>
                    <Tab label="resources.Transaction.tabs.tab1">
                        <TextField source="id" />
                        <TextField source="txid" />
                        <TextField source="orderInBlock" />
                        <ReferenceField label="所属区块哈希" source="block.id" reference="Block" linkType="show">
                            <TextField source="hash" style={{ wordBreak: "break-all" }} />
                        </ReferenceField>
                        <TextField source="signature.signature" style={{ wordBreak: "break-all" }} />
                        <TextField source="signature.certID.creditCode" />
                        <TextField source="signature.certID.certName" />
                        <DateField source="timestamp" showTime options={{ hour12: false }} />
                    </Tab>
                    <Tab label="resources.Transaction.tabs.tab2">
                        <TextField source="type" />
                        <TextField source="chaincodeID.chaincodeName" />
                        <NumberField source="chaincodeID.version" />
                        {
                            controllerProps.record && controllerProps.record.type === "CHAINCODE_DEPLOY"
                && <CodeField
                    source="chaincodeDeployParams.codePackage"
                    language={
                        controllerProps.record.chaincodeDeployParams.codeLanguageType.substring(
                            controllerProps.record.chaincodeDeployParams.codeLanguageType.lastIndexOf("_") + 1,
                        ).toLowerCase()
                    }
                    expansionSummary={[
                        controllerProps.record.chaincodeID.chaincodeName,
                        controllerProps.record.chaincodeID.version,
                        controllerProps.record.chaincodeDeployParams.codeLanguageType,
                    ]}
                />
                        }
                        {
                            controllerProps.record && controllerProps.record.type === "CHAINCODE_DEPLOY"
                && <RichTextField source="chaincodeDeployParams.legalProse" />
                        }
                        {
                            controllerProps.record && controllerProps.record.type === "CHAINCODE_DEPLOY"
                && <TextField source="chaincodeDeployParams.codeLanguageType" />
                        }
                        {
                            controllerProps.record && controllerProps.record.type === "CHAINCODE_INVOKE"
                && <TextField source="chaincodeInvokeParams.function" />
                        }
                        {
                            controllerProps.record && controllerProps.record.type === "CHAINCODE_INVOKE"
                && <ArgField source="chaincodeInvokeParams.args" />
                        }
                        {
                            controllerProps.record && controllerProps.record.type === "CHAINCODE_SET_STATE"
                && <BooleanField source="chaincodeSetStateParams.state" />
                        }
                    </Tab>
                </TabbedShowLayout>
            </ShowView>
        }
    </ShowController>
);

export class TransCreate extends React.Component {
    constructor(props) {
        super(props);
        this.receiveMessage = this.receiveMessage.bind(this);
        this.state = {};
    }

    componentDidMount() {
        window.addEventListener("message", this.receiveMessage, false);
    }

    componentWillUnmount() {
        window.removeEventListener("message", this.receiveMessage, false);
    }

    receiveMessage(event) {
    // For Chrome, the origin property is in the event.originalEvent
    // object. 
        const origin = event.origin || event.originalEvent.origin;
        console.log(event);
        this.setState({ iptVal: event.data });
        event.source.postMessage("received");
        if (origin !== "http://example.org:8080") {}
    }

    render() {
        const { iptVal } = this.state;
        const {
            chaincodeName,
            chaincodeVersion,
            chaincodeFunction,
            chaincodeArgs,
        } = this.props.location.state ? this.props.location.state : {};
        const transactionTypeChoices = [
            { id: "CHAINCODE_DEPLOY", name: "CHAINCODE_DEPLOY" },
            { id: "CHAINCODE_INVOKE", name: "CHAINCODE_INVOKE" },
            { id: "CHAINCODE_SET_STATE", name: "CHAINCODE_SET_STATE" },
        ];
        return (
            <Create {...this.props}>
                <TabbedForm toolbar={<CreateToolbar />}>
                    <FormTab label="resources.Transaction.tabs.tab1">
                        <RadioButtonGroupInput label="交易类型" source="type" defaultValue={"CHAINCODE_INVOKE"}
                            choices={transactionTypeChoices} validate={required()} />
                        <LongTextInput source="chaincodeName" defaultValue={chaincodeName} validate={required()} />
                        <NumberInput source="chaincodeVersion" defaultValue={chaincodeVersion} validate={required()} />
                        <FormDataConsumer>
                            {
                                ({ formData, ...rest }) => {
                                    const transactionType = formData.type;
                                    if (transactionType === "CHAINCODE_DEPLOY") {
                                        const chaincodeLanguageTypeChoices = [
                                            { id: "CODE_JAVASCRIPT", name: "CODE_JAVASCRIPT" },
                                            { id: "CODE_SCALA", name: "CODE_SCALA" },
                                        ];
                                        return (
                                            <div style={{ display: "inline-grid" }}>
                                                <LongTextInput source="chaincodeDeployParams.codePackage" validate={required()} {...rest} />
                                                <LongTextInput source="chaincodeDeployParams.legalProse" validate={required()} {...rest} />
                                                <RadioButtonGroupInput source="chaincodeDeployParams.codeLanguageType"
                                                    choices={chaincodeLanguageTypeChoices}
                                                    validate={required()}
                                                    {...rest}
                                                />
                                            </div>
                                        );
                                    }
                                    if (transactionType === "CHAINCODE_INVOKE") {
                                        return (
                                            <div style={{ display: "inline-grid" }}>
                                                <TextInput
                                                    source="chaincodeInvokeParams.chaincodeFunction"
                                                    defaultValue={chaincodeFunction}
                                                    validate={required()}
                                                    {...rest}
                                                />
                                                <ArrayInput
                                                    source="chaincodeInvokeParams.chaincodeFunctionArgs"
                                                    defaultValue={chaincodeArgs ? chaincodeArgs.map((v) => ({ arg: v })) : null}
                                                    validate={required()} {...rest}>
                                                    <SimpleFormIterator>
                                                        <LongTextInput label="参数" source="arg" validate={required()} {...rest} />
                                                    </SimpleFormIterator>
                                                </ArrayInput>
                                            </div>
                                        );
                                    }
                                    if (transactionType === "CHAINCODE_SET_STATE") {
                                        const stateChoices = [
                                            { id: "true", name: "启用" },
                                            { id: "false", name: "禁用" },
                                        ];
                                        return (
                                            <RadioButtonGroupInput source="chaincodeSetStateParams.state"
                                                choices={stateChoices}
                                                validate={required()}
                                                {...rest} />
                                        );
                                    }
                                }
                            }
                        </FormDataConsumer>
                        <ReferenceInput id="selectAccountName" label="账号" source="account.creditCode"
                            reference="accounts" validate={required()} >
                            <SelectInput optionText="name" optionValue="creditCode" />
                        </ReferenceInput>
                        <FormDataConsumer>
                            {
                                ({ formData, ...rest }) => (
                                    <div id="selectKeypairName" style={{ display: "inline-block" }} >
                                        <ReferenceInput id="selectKeypairName" label="密钥对" source="account.keypairID"
                                            reference="keypairs"
                                            filter={{ ownerCreditCode: formData.account ? formData.account.creditCode : "none" }}
                                            validate={required()}
                                            {...rest}>
                                            <SelectInput optionText="name" optionValue="id" {...rest} />
                                        </ReferenceInput>
                                    </div>
                                )
                            }
                        </FormDataConsumer>
                        <TextInput label="密钥密码" source="keypairPwd" defaultValue="" type="password" />
                    </FormTab>
                </TabbedForm>
            </Create>
        );
    }
}
